package com.tticar.invmanager.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.tticar.invmanager.common.Enum.CodeType;
import com.tticar.invmanager.common.shiro.LoginUser;
import com.tticar.invmanager.entity.InRepositoryDetail;
import com.tticar.invmanager.entity.MMaterielSku;
import com.tticar.invmanager.entity.vo.*;
import com.tticar.invmanager.mapper.InRepositoryDetailMapper;
import com.tticar.invmanager.service.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 入库单详情 服务实现类
 * </p>
 *
 * @author joeyYan
 * @since 2018-08-02
 */
@Service
public class InRepositoryDetailServiceImpl extends ServiceImpl<InRepositoryDetailMapper, InRepositoryDetail> implements IInRepositoryDetailService {

    @Autowired
    private ICodeCounterService codeCounterService;

    @Autowired
    private IRepositoryCountService repositoryCountService;
    @Autowired
    private IMMaterielSkuService skuService;
    @Autowired
    private ISysDictService sysDictService;

    @Override
    public Page selectPage(InRepositoryDetailSearchDto searchDto, MyPage<InRepositoryDetail> page) {
        List<Map> maps = baseMapper.selectAllByMapper(page, searchDto);
        List<Map> repository = sysDictService.selList(DictCodes.get("repository"));
        for (int i = 0;i < maps.size(); i++) {
            for (int j =0;j<repository.size();j++) {
                if (maps.get(i).get("type").toString().equals(repository.get(j).get("value"))) {
                    maps.get(i).put("typeName", repository.get(j).get("text"));
                }
            }
        }
        return page.setRecords(maps);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<Long> ids) {
        List list = new ArrayList();
        for (Long id : ids) {
            InRepositoryDetail inRepositoryDetail = new InRepositoryDetail();
            inRepositoryDetail.setId(id);
            //删除为-1，区分删除和禁用
            inRepositoryDetail.setStatus(-1);
            list.add(inRepositoryDetail);
        }
        this.updateBatchById(list);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    @Deprecated
    public void batchInsert(JSONArray list) {
        for (int i = 0; i < list.size() - 1; i++) {
            InRepositoryDetail inRepositoryDetail = JSON.parseObject(list.get(i).toString(), new TypeReference<InRepositoryDetail>() {
            });
            String code = codeCounterService.getOrderCode(CodeType.RK);
            inRepositoryDetail.setCode(code);
            insertOrUpdate(inRepositoryDetail);
        }

    }

    /**
     * 批量新增入库单
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void addInRepositoryDetail(InRepositoryAddDTO dto) {
        //获取当前操作人
        Subject subject = SecurityUtils.getSubject();
        LoginUser loginUser = (LoginUser) subject.getPrincipal();
        String username = loginUser.getUsername();

        List<InRepositoryGoodsDTO> goodsList = dto.getInRepositoryGoodsDTOs();
        String code = codeCounterService.getOrderCode(CodeType.RK);
        for (InRepositoryGoodsDTO goods : goodsList) {
            InRepositoryDetail inRepositoryDetail = new InRepositoryDetail();
            //批量插入记录的公共数据
            inRepositoryDetail.setType(dto.getInRepositoryType());
            inRepositoryDetail.setOrderTime(dto.getOrderTime());
            inRepositoryDetail.setCode(code);
            inRepositoryDetail.setUsername(username);
            //批量插入记录的各自数据
            inRepositoryDetail.setBatchNumber(StringUtils.isNotEmpty(goods.getBatchCode()) ? goods.getBatchCode() : codeCounterService.getBatchCode());
            inRepositoryDetail.setSkuId(goods.getSkusId());
            inRepositoryDetail.setPositionId(goods.getPositionId());
            inRepositoryDetail.setWearhouseId(goods.getWearhouseId());
            inRepositoryDetail.setProviderId(goods.getRalativeId());
            inRepositoryDetail.setCount(goods.getCount());
            inRepositoryDetail.setRemark(goods.getRemark());

            repositoryCountService.updateRepositoryCount(goods.getSkusId(), goods.getWearhouseId(), goods.getCount());

            insertOrUpdate(inRepositoryDetail);
        }
    }

    @Override
    public Integer getBatchCodeIsExsit(String batchCode) {
        Wrapper wrapper = new EntityWrapper();
        wrapper.eq("batch_number", batchCode);
        Map result = this.selectMap(wrapper);
        return result != null ? 1 : 0;
    }

    @Override
    public List<Map> batchCodeGrid(Long skuId) {
        return this.baseMapper.batchCodeGrid(skuId);
    }

    @Override
    public List<Map> getSkuBatchCodeForOut(String skuIds) {
        return this.baseMapper.getSkuBatchCodeForOut(skuIds);
    }

    @Override
    public List<Map> getDetailByCode(String code) {
        return this.baseMapper.getDetailByCode(code);
    }

    @Override
    public List<Map> getDetailBySku(Long houseId, Long goodsId, Long skuId) {
        Map<String, Object> map = new HashMap<>();
        map.put("houseId", houseId);
        if(skuId != null) {
            map.put("skuIds", skuId);
        } else {
            Wrapper wrapper = new EntityWrapper();
            wrapper.eq("mid", goodsId);
            List<MMaterielSku> list = this.skuService.selectList(wrapper);

            String ids = "";
            for(MMaterielSku sku : list) {
                ids += "," + sku.getId();
            }
            if(ids != "") {
                ids = ids.substring(1);
            }
            map.put("skuIds", ids);
        }

        return this.baseMapper.getDetailBySkuNew(map);
    }

    @Override
    public String getSkuHouseByNum(Long skuId, Integer num, Long houseId) {
        Map<String, Object> params = new HashMap<>();
        params.put("skuId", skuId);
        params.put("houseId", houseId);
        List<Map> list = this.baseMapper.getSkuHouseByNum(params);
        int total = 0;
        String house = "";
        for(Map map : list) {
            int need = num - total;
            if(need == 0) {
                break;
            }
            int cur = Integer.parseInt(map.get("num").toString());
            if(need > cur) { //当前批次不够
                need = cur;
            }
            total += need;
            //仓库ID/NAME/库位ID/NAME/批号/库存数目/出库数目
            house += "," + map.get("houseId") + "_" + map.get("houseName") + "_" + map.get("positionId") + "_" + map.get("positionName")
                    + "_" + map.get("batchCode") + "_" + map.get("num") + "_" + need;
        }
        if(!house.equals("")) {
            house = house.substring(1);
        }
        return house;
    }

    @Override
    public String getSkuHouseByNumAndTenantId(Long skuId, Integer num, Long houseId,Long tenantId) {
        Map<String, Object> params = new HashMap<>();
        params.put("skuId", skuId);
        params.put("houseId", houseId);
        params.put("tenantId", tenantId);
        List<Map> list = this.baseMapper.getSkuHouseByNumAndTenantId(params);
        int total = 0;
        String house = "";
        for(Map map : list) {
            int need = num - total;
            if(need == 0) {
                break;
            }
            int cur = Integer.parseInt(map.get("num").toString());
            if(need > cur) { //当前批次不够
                need = cur;
            }
            total += need;
            //仓库ID/NAME/库位ID/NAME/批号/库存数目/出库数目
            house += "," + map.get("houseId") + "_" + map.get("houseName") + "_" + map.get("positionId") + "_" + map.get("positionName")
                    + "_" + map.get("batchCode") + "_" + map.get("num") + "_" + need;
        }
        if(!house.equals("")) {
            house = house.substring(1);
        }
        return house;
    }

    @Override
    public Long getSkuNumByBatchCode(Long skuId, String batchCode) {
        Map<String, Object> map = new HashMap<>();
        map.put("skuId", skuId);
        map.put("batchCode", batchCode);
        return this.baseMapper.getSkuNumByBatchCode(map);
    }

    @Override
    public List<Map> getBatchListByHouseId2SkuId(Long houseId, Long skuId) {
        Map<String, Object> map = new HashMap<>();
        map.put("houseId", houseId);
        map.put("skuId", skuId);
        return this.baseMapper.getBatchListByHouseId2SkuId(map);
    }

    @Override
    public Double getSkuAvgCostByHouseId(Long houseId, Long skuId) {
        Map<String, Object> map = new HashMap<>();
        map.put("houseId", houseId);
        map.put("skuId", skuId);
        return this.baseMapper.getSkuAvgCostByHouseId(map);
    }

    @Override
    public String getSkuHouseByHouseId(Long houseId, Long skuId) {
        Map<String, Object> map = new HashMap<>();
        map.put("houseId", houseId);
        map.put("skuId", skuId);
        List<Map> list = this.baseMapper.getSkuHouseByHouseId(map);
        if(list.size() == 0) {
            return "";
        }
        String house = (String) list.get(0).get("house");
        if(StringUtils.isEmpty(house)) {
            return "";
        }
        return house;
    }

    @Override
    public String getMaterielHouseByHouseId(Long houseId, Long materielId) {
        Map<String, Object> map = new HashMap<>();
        map.put("houseId", houseId);
        map.put("materielId", materielId);
        List<Map> list = this.baseMapper.getMaterielHouseByHouseId(map);
        if(list.size() == 0) {
            return "";
        }
        String house = (String) list.get(0).get("house");
        if(StringUtils.isEmpty(house)) {
            return "";
        }
        return house;
    }
}
